<!DOCTYPE html>
<html prefix="
og: http://ogp.me/ns#
article: http://ogp.me/ns/article#
" lang="zh_cn">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>python meta class | vincent blog</title>
<link href="../../assets/css/all-nocdn.css" rel="stylesheet" type="text/css">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../../rss.xml">
<link rel="canonical" href="https://wisonwang.github.io/posts/python-meta-class/">
<!--[if lt IE 9]><script src="/assets/js/html5.js"></script><![endif]--><meta name="author" content="vincent wang">
<meta property="og:site_name" content="vincent blog">
<meta property="og:title" content="python meta class">
<meta property="og:url" content="https://wisonwang.github.io/posts/python-meta-class/">
<meta property="og:description" content="python的元类(metaclass)和虚基类（ABC）
== metaclass  ==
== ABC虚基类 ==



python 元类






In [11]:

    
class a:
    def __init__(self, data):
        self.data = data
        
    def getd3(self):
        retu">
<meta property="og:type" content="article">
<meta property="article:published_time" content="2019-04-15T18:10:46+08:00">
</head>
<body>
    <section class="social"><ul>
<li><a href="../../index.html" title="Home"><i class="icon-home"></i></a></li>
            <li><a href="../../archive.html" title="文章存档"><i class="icon-archive"></i></a></li>
            <li><a href="../../categories/" title="标签"><i class="icon-tags"></i></a></li>
            <li><a href="../../pages/about" title="About"><i class="icon-about"></i></a></li>
            <li><a href="../../rss.xml" title="RSS 源"><i class="icon-rss"></i></a></li>
            <li><a href="https://twitter.com/wisonwang" title="My Twitter"><i class="icon-twitter"></i></a></li>
            <li><a href="https://github.com/wisonwang" title="My Github"><i class="icon-github"></i></a></li>

        </ul></section><section class="page-content"><div class="content" rel="main">
    <div class="post">
        <h1 class="p-name entry-title" itemprop="headline name">python meta class</h1>

        <div class="meta">
            <div class="authordate">
                <time class="timeago" datetime="2019-04-15T18:10:46+08:00">2019-04-15 18:10</time>
            
                      |  
        <a href="index.ipynb" id="sourcelink">源代码</a>

            </div>
            
        </div>
        <div class="body">
            <div tabindex="-1" id="notebook" class="border-box-sizing">
    <div class="container" id="notebook-container">

<div class="cell border-box-sizing text_cell rendered">
<div class="prompt input_prompt">
</div>
<div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>python的元类(metaclass)和虚基类（ABC）</p>
<p>== metaclass  ==</p>
<p>== ABC虚基类 ==</p>
<!-- TEASER_END -->


<p><a href="https://www.ibm.com/developerworks/cn/linux/l-pymeta/index.html" title="python 元类">python 元类</a></p>

</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [11]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="k">class</span> <span class="nc">a</span><span class="p">:</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>
        
    <span class="k">def</span> <span class="nf">getd3</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">*</span> <span class="mi">3</span>
    
 
<span class="k">class</span> <span class="nc">MyMeta</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__new__</span><span class="p">(</span><span class="n">metaname</span><span class="p">,</span> <span class="n">classname</span><span class="p">,</span> <span class="n">baseclasses</span><span class="p">,</span> <span class="n">attrs</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'New called with'</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'metaname'</span><span class="p">,</span> <span class="n">metaname</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'classname'</span><span class="p">,</span> <span class="n">classname</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'baseclasses'</span><span class="p">,</span> <span class="n">baseclasses</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'attrs'</span><span class="p">,</span> <span class="n">attrs</span><span class="p">)</span>
        <span class="n">attrs</span><span class="p">[</span><span class="s1">'getdata'</span><span class="p">]</span> <span class="o">=</span> <span class="n">a</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="s1">'getd3'</span><span class="p">]</span>
        <span class="c1"># attrs['getdata'] = a.getd3</span>
        <span class="k">return</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="n">metaname</span><span class="p">,</span> <span class="n">classname</span><span class="p">,</span> <span class="n">baseclasses</span><span class="p">,</span> <span class="n">attrs</span><span class="p">)</span>
    
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="n">classobject</span><span class="p">,</span> <span class="n">classname</span><span class="p">,</span> <span class="n">baseclasses</span><span class="p">,</span> <span class="n">attrs</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'init called with'</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'classobject'</span><span class="p">,</span> <span class="n">classobject</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'classname'</span><span class="p">,</span> <span class="n">classname</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'baseclasses'</span><span class="p">,</span> <span class="n">baseclasses</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s1">'attrs'</span><span class="p">,</span> <span class="n">attrs</span><span class="p">)</span>

<span class="c1"># py2 和py3对metaclass工作方式不也一样，一下是py3写法</span>
<span class="k">class</span> <span class="nc">Kls</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">MyMeta</span><span class="p">):</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">data</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span>

    <span class="k">def</span> <span class="nf">printd</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
        
<span class="n">ik</span> <span class="o">=</span> <span class="n">Kls</span><span class="p">(</span><span class="s1">'arun'</span><span class="p">)</span>
<span class="n">ik</span><span class="o">.</span><span class="n">printd</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">ik</span><span class="o">.</span><span class="n">getdata</span><span class="p">())</span>
</pre></div>

    </div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">

    <div class="prompt"></div>


<div class="output_subarea output_stream output_stdout output_text">
<pre>New called with
metaname &lt;class '__main__.MyMeta'&gt;
classname Kls
baseclasses ()
attrs {'__module__': '__main__', '__qualname__': 'Kls', '__init__': &lt;function Kls.__init__ at 0x105be4c80&gt;, 'printd': &lt;function Kls.printd at 0x105be4598&gt;}
init called with
classobject &lt;class '__main__.Kls'&gt;
classname Kls
baseclasses ()
attrs {'__module__': '__main__', '__qualname__': 'Kls', '__init__': &lt;function Kls.__init__ at 0x105be4c80&gt;, 'printd': &lt;function Kls.printd at 0x105be4598&gt;, 'getdata': &lt;function a.getd3 at 0x105be4bf8&gt;}
arun
arunarunarun
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [16]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABCMeta</span>


<span class="c1"># 构造元类</span>
<span class="k">def</span> <span class="nf">with_metaclass</span><span class="p">(</span><span class="n">meta</span><span class="p">,</span> <span class="o">*</span><span class="n">bases</span><span class="p">):</span>
    <span class="c1"># This requires a bit of explanation: the basic idea is to make a</span>
    <span class="c1"># dummy metaclass for one level of class instantiation that replaces</span>
    <span class="c1"># itself with the actual metaclass.  Because of internal type checks</span>
    <span class="c1"># we also need to make sure that we downgrade the custom metaclass</span>
    <span class="c1"># for one level to something closer to type (that's why __call__ and</span>
    <span class="c1"># __init__ comes back from type etc.).</span>
    <span class="c1">#</span>
    <span class="c1"># This has the advantage over six.with_metaclass in that it does not</span>
    <span class="c1"># introduce dummy classes into the final MRO.</span>
    <span class="k">class</span> <span class="nc">metaclass</span><span class="p">(</span><span class="n">meta</span><span class="p">):</span>
        <span class="fm">__call__</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__call__</span>
        <span class="fm">__init__</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__init__</span>
        <span class="k">def</span> <span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">this_bases</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">this_bases</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="k">return</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="p">(),</span> <span class="n">d</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">meta</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">d</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">metaclass</span><span class="p">(</span><span class="s1">'temporary_class'</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="p">{})</span>


<span class="k">class</span> <span class="nc">MyList</span><span class="p">(</span><span class="n">with_metaclass</span><span class="p">(</span><span class="n">ABCMeta</span><span class="p">,</span>  <span class="p">)):</span>
    <span class="k">pass</span>


<span class="n">MyList</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="nb">list</span><span class="p">)</span>

<span class="k">assert</span> <span class="nb">issubclass</span><span class="p">(</span><span class="nb">list</span><span class="p">,</span> <span class="n">MyList</span><span class="p">)</span>
</pre></div>

    </div>
</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [10]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABC</span>
<span class="kn">import</span> <span class="nn">collections</span>

<span class="nb">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span>
</pre></div>

    </div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">

    <div class="prompt"></div>


<div class="output_subarea output_stream output_stdout output_text">
<pre>&lt;class 'int'&gt;
</pre>
</div>
</div>

</div>
</div>

</div>
<div class="cell border-box-sizing code_cell rendered">
<div class="input">
<div class="prompt input_prompt">In [8]:</div>
<div class="inner_cell">
    <div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">collections</span><span class="o">.</span><span class="n">Set</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="nb">set</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="nb">set</span><span class="p">)</span>

<span class="nb">print</span><span class="p">(</span><span class="nb">set</span><span class="o">.</span><span class="vm">__doc__</span><span class="p">)</span>
</pre></div>

    </div>
</div>
</div>

<div class="output_wrapper">
<div class="output">


<div class="output_area">

    <div class="prompt"></div>


<div class="output_subarea output_stream output_stdout output_text">
<pre>&lt;class 'collections.abc.Set'&gt;
&lt;class 'type'&gt;
&lt;class 'set'&gt;
set() -&gt; new empty set object
set(iterable) -&gt; new set object

Build an unordered collection of unique elements.
</pre>
</div>
</div>

</div>
</div>

</div>
    </div>
  </div>

        </div>
                <ul class="pager hidden-print">
<li class="previous">
                <a href="../python-function-tools/" rel="prev" title="python function tools">前一篇</a>
            </li>
            <li class="next">
                <a href="../zi-jian-httpszhan-dian/" rel="next" title="自建https站点">后一篇</a>
            </li>
        </ul>
<div id="disqus_thread"></div>
        <script>
        var disqus_shortname ="wisonwanghomepage",
            disqus_url="https://wisonwang.github.io/posts/python-meta-class/",
        disqus_title="python meta class",
        disqus_identifier="cache/posts/python-meta-class.html",
        disqus_config = function () {
            this.language = "zh_cn";
        };
        (function() {
            var dsq = document.createElement('script'); dsq.async = true;
            dsq.src = 'https://' + disqus_shortname + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
    </script><noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a>
</noscript>
    <a href="https://disqus.com" class="dsq-brlink" rel="nofollow">Comments powered by <span class="logo-disqus">Disqus</span></a>


    </div>
                     <footer id="footer"><p>Contents © 2020         <a href="mailto:fangfu2012@gmail.com">vincent wang</a> - Powered by         <a href="https://getnikola.com" rel="nofollow">Nikola</a>         </p>
            
        </footer>
</div>
    </section><script src="../../assets/js/all-nocdn.js" type="text/javascript"></script><script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"> </script><script type="text/x-mathjax-config">
    MathJax.Hub.Config({tex2jax: {inlineMath: [['$latex ','$'], ['\\(','\\)']]}});
    </script><script type="text/javascript">
            $(function(){
                $('.timeago').timeago();
            });
        </script>
</body>
</html>
